package arsw.twitter.controller;

import java.util.LinkedList;
import java.util.Map;
import java.util.TreeMap;

import arsw.twitter.common.IController;
import arsw.twitter.common.Mensaje;
import arsw.twitter.model.Observer;
import arsw.twitter.model.Subject;
import arsw.twitter.model.Usuario;

public class Controller implements IController {
	
	private Map<String, Usuario> registeredUsers = new TreeMap<String, Usuario>();
	
	static private Iterable<Mensaje> emptyMessages = new LinkedList<Mensaje>();
	
	static private Controller instance = new Controller();
	
	private Controller() {
	}
	
	static public Controller getInstance() {
		return instance;
	}
	
	@Override
	public void registrarUsuario(String name) {
		if (registeredUsers.containsKey(name)) {
			System.err.println("Usuario "+ name + " ya esta definido");
		} else {		
			final Usuario u = Usuario.newInstance(name);		
			registeredUsers.put(name, u);
			System.out.println("Se registro el usuario: " + name);
		}
	}
	
	/* (non-Javadoc)
	 * @see controller.UserController#publicar(java.lang.String, java.lang.String)
	 */
	@Override
	public void publicar(String user, String message) {
		if (esUsuarioRegistrado(user)) {
			Usuario u = registeredUsers.get(user);
			u.send(message);
		}
	}
	
	/* (non-Javadoc)
	 * @see controller.UserController#seguir(java.lang.String, java.lang.String)
	 */
	@Override
	public void seguir(String observerId, String subjectId ) {
		if (esUsuarioRegistrado(subjectId) && esUsuarioRegistrado(observerId)) {
			Subject<Mensaje> u = registeredUsers.get(subjectId);
			Observer<Mensaje> o = registeredUsers.get(observerId);
			u.registerObserver(o);
		}
	}

	/* (non-Javadoc)
	 * @see controller.UserController#suspender(java.lang.String, java.lang.String)
	 */
	@Override
	public void suspender(String observerId, String subjectId) {
		if (esUsuarioRegistrado(subjectId) && esUsuarioRegistrado(observerId)) {
			Subject<Mensaje> u = registeredUsers.get(subjectId);
			Observer<Mensaje> o = registeredUsers.get(observerId);
			u.removeObserver(o);
		}
	}

	@Override
	public void darDeBajaUsuario(String userId) {
		for(String user : registeredUsers.keySet()) {
			suspender(userId, user);
		}
		registeredUsers.remove(userId);
	}

	@Override
	public Iterable<Mensaje> leerMensajes(String name) {
		Iterable<Mensaje> result;
        if (esUsuarioRegistrado(name)) {
        	Usuario u = registeredUsers.get(name);
		    result = u.getMessages();
        } else {
        	result = emptyMessages;
        }
        return result;
	}

	@Override
	public boolean esUsuarioRegistrado(String name) {
		return registeredUsers.containsKey(name);
	}

}
